package JasPerl::JSTL::Core::Exceptions;

use 5.010;
use strict;
use warnings;

use JasPerl::Exceptions;

my %RESOURCES = (
    PARAM_OUTSIDE_PARENT => '&lt;param&gt; outside &lt;import&gt; or &lt;url&gt;',
    FOREACH_INVALID_ITEMS => 'Invalid "items" type in &lt;forEach&gt;',
    IMPORT_BAD_RELATIVE => 'Both "context" and "url" must start with "/" in &lt;import&gt;',
    IMPORT_NO_DISPATCHER => 'Unable to get RequestDispatcher in &lt;imüprt&gt;',
    SET_BAD_SCOPE => 'Invalid "scope" attribute for &lt;set&gt;',
    SET_INVALID_PROPERTY => 'Invalid property in &lt;set&gt;',
    SET_INVALID_TARGET => 'Attempt to set the property of an invalid object in &lt;set&gt;',
    SET_NO_VALUE => 'Need either non-whitespace body or "value" attribute in &lt;set&gt;',
    WHEN_OUTSIDE_CHOOSE => '&lt;when&gt; outside &lt;choose&gt;',
    OTHERWISE_OUTSIDE_CHOOSE => '&lt;otherwise&gt; outside &lt;choose&gt;'
);

use Exception::Class (
    'JasPerl::JSTL::Core::Exception' => {
        isa => 'JasPerl::JspTagException',
        description => "Default exception"
    },
    'JasPerl::JSTL::Core::IllegalAttributeTypeException' => {
        isa => 'JasPerl::JspTagException',
        description => "Thrown when a tag attribute is of invalid type"
    },
    'JasPerl::JSTL::Core::IllegalParentTagException' => {
        isa => 'JasPerl::JspTagException',
        description => "Thrown when a tag appears outside its legal parent(s)"
    },
    'JasPerl::JSTL::Core::NullAttributeException' => {
        isa => 'JasPerl::JspTagException',
        description => "JspTagException thrown when a tag attribute is null"
    },
    'JasPerl::JSTL::Core::UnsupportedAttributeException' => {
        isa => 'JasPerl::JspTagException',
        description => "JspTagException thrown for unsupported tag attributes"
    }
);

package JasPerl::JSTL::Core::Exception;

sub new {
    my ($class, $key, @params) = @_;
    if (exists $RESOURCES{$key}) {
        return $class->SUPER::new(sprintf($RESOURCES{$key}, @params));
    } else {
        return $class->SUPER::new("???$key???");
    }
}

package JasPerl::JSTL::Core::IllegalAttributeTypeException;

sub new {
    my ($class, $tag, $attr, $reftype) = @_;
    my $msg = "Attribute '$attr' evaluated to " .
        ($reftype ? "reference type '$reftype'" : "scalar or 'null'") .
        "in &lt;$tag&gt;";
    return $class->SUPER::new($msg);
}

package JasPerl::JSTL::Core::IllegalParentTagException;

sub new {
    my ($class, $tag) = @_;
    my $msg = "Invalid use of &lt;$tag&gt; outside legitimate parent tag(s)";
    return $class->SUPER::new($msg);
}

package JasPerl::JSTL::Core::NullAttributeException;

sub new {
    my ($class, $tag, $attr) = @_;
    my $msg = "Attribute '$attr' evaluated to 'null' or '' in &lt;$tag&gt;";
    return $class->SUPER::new($msg);
}

package JasPerl::JSTL::Core::UnsupportedAttributeException;

sub new {
    my ($class, $tag, $attr) = @_;
    my $msg = "Attribute '$attr' not supported (yet) in &lt;$tag&gt;";
    return $class->SUPER::new($msg);
}

1;
